<?php

	namespace Aspic;
	
	/**
	* Registre avec système de groupe (sous-registres)
	* 
	* Les variables du registre sont classées par groupe. Ce qui permet d'avoir des sous-registres.
	* Les méthodes get($varName) et set($varName,$varValue) permettent de gerer les valeurs du registre.
	* 
	* Lorsque ces méthodes sont appelées statiquement, les variables sont stockées dans le registre global,
	* elles disposent d'un argument supplémentaire permettant de définir le sous registre auxquelles les variables
	* appartiendront.
	* 
	* Si une variable n'est pas trouvée dans un sous-registre, la méthode get retournera celle du registre global, si elle existe, 
	* et la variable du sous registre en cas de conflit.
	* 
	* La création d'un objet Registre permet de ne devoir spécifier qu'a la construction de l'objet le sous-registre auxquelle on
	* souhaite que les variables soient assignées sans devoir spécifier ce sous-registre en dernier argument de la méthode
	* static get() ou set() à chaque fois qu'on veut enregistrer une variable
	* 
	* Nécéssite PHP 5.3.0 (__callStatic)
	* 
	*/
	class Registry {
		const GET_METHOD = 'get';
		const SET_METHOD = 'set';
		const UNSET_METHOD = 'destroy'; // unset is reserved by php
	
		/**
		* @var string $_group Groupe courant
		*/
		protected $_group;
		/**
		* @var Array $_vars Pour chaque variable du registre on distingue deux clés : la valeur et le groupe
		*/
		protected static $_vars;
		
		public function __construct($group) {
			$this->_group = $group;
		}
		
		public function __call($meth, $args) {
			$args[count($args)] = $this->group;
			
			return static::call($meth, $args);
		}
		
		// Need PHP 5.3.0 or greather
		public static function __callStatic($meth, $args) {
			return static::call($meth, $args);
		}
		
		public static function call($meth, $args) {
			if($meth == static::GET_METHOD) {
				return call_user_func_array('static::_getVar', $args);
			}
			elseif($meth == static::SET_METHOD) {
				return call_user_func_array('static::_setVar', $args);
			}
			elseif($meth == static::UNSET_METHOD) {
				return call_user_func_array('static::_unsetVar', $args);
			}
			else {
				throw new BadMethodCallException();
			}
		}
		
		/**
		 * Get all vers of current group
		 */
		public function getAll() {
			return static::$_vars[$this->_group];
		}
		
		public static function getAllFromGroup($groupName) {
			return static::$_vars[$groupName];
		}
		
		protected static function _getVar($varName, $group = 'global') {
			if(isset(static::$_vars[$group][$varName])) {
				return static::$_vars[$group][$varName];
			}
			elseif(isset(static::$_vars['global'][$varName])) {
				return static::$_vars['global'][$varName];
			}
			else {
				return null;
			}
		}
		
		protected static function _setVar($varName, $value, $group = 'global') {
			static::$_vars[$group][$varName] = $value;
		}
		
		protected static function _unsetVar($varName, $group = 'global') {
			unset(static::$_vars[$group][$varName]);
		}
		
	}

// $reg = new Registry('group');
// $reg->set('a','b');
// Registry::set('c','d');
// Registry::set('a','b');
// var_dump($reg->get('a'));
// var_dump($reg->get('c'));

// var_dump(Registry::get('a'));
// var_dump(Registry::get('a','group'));

?>
